<?php
class Cmysql
{
	public $dbobj	= null ;
	public $debug	= false;
	public $table	= '';
	public $hash	= array('0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z');

	static public $showObj	= array();
	
	function __construct( $obj = null ,$debug =false)
	{
		$this->dbobj = $obj;
		$this->debug = $debug;
	}

	function __destruct()
	{
		unset($dbobj);
	}

	// 初始化
	static public function ini( $type = 'w', $db = 'default', $debug = false)
	{
		if(isset(self::$showObj[$db][$type]))
		{
			return self::$showObj[$db][$type];
		}
		$obj						= XINHUA::mysql( $type, $db );
		$class						= __CLASS__;
		self::$showObj[$db][$type]	= new $class( $obj, $debug );
		unset($obj);
		return self::$showObj[$db][$type];
	}

	static public function Time33( $str , $maxLen = 0 )
	{
		$hash 	= 0;
		$s 		= md5($str);
		$seed 	= 5;
		$len 	= 32;
		for($i = 0; $i < $len; $i++)
		{
			$hash = ( $hash << $seed ) + $hash + ord( $s{$i} );
		}
		$table 	= $hash & 0x7FFFFFFF ;
		$maxLen =  $maxLen == 64  ? 63 : $maxLen ;
		if( $maxLen )
		{
			return ($table % $maxLen);
		}
		else
		{
			return $table ;
		}
	}

	// 哈希分表
	/*
	public function TableHash( $table , $str, $maxLen = 64 )
	{
		$_hash 	= 0;
		$s 		= md5($str);
		$seed 	= 5;
		$len 	= 32;
		for($i = 0; $i < $len; $i++)
		{
			$_hash = ( $_hash << $seed ) + $_hash + ord( $s{$i} );
		}
		$_table	= $_hash & 0x7FFFFFFF ;
		$maxLen	=  $maxLen == 64  ? 63 : $maxLen ;
		$rs		= !empty($maxLen) ? ($_table % $maxLen) + 1 : 1;
		return $table.'_'.$rs;
	}
	*/
	
	public function TableHash( $table , $str, $maxLen = 64 )
	{
		$_hash 	= 0;
		$s 		= md5($str);
		$seed 	= 5;
		$len 	= 32;
		for($i = 0; $i < $len; $i++)
		{
			$_hash += (int)array_search($s{$i},$this->hash);
		}
		$rs 	= ($_hash % $maxLen) + 1;
		return $table.'_'.$rs;
	}

	// QUERY
	public function query( $sql )
	{ 
		if($this->debug) echo $sql;
		return  $this->dbobj->query( $sql );
	}

	public function exec( $sql )
	{
		if($this->debug) echo $sql;
		return $this->dbobj->exec( $sql );
	}

	// 处理数据
	public function handleData( $data )
	{
		$sql = '';
		if(!empty( $data ) )
		{
			foreach($data as $k=>$v)
			{
				if(is_array($v))
				{
					$sql .= " `".$k."`=".$v[0]." ,";
				}else{
					$sql .= " `".$k."`='".$v."' ,";
				}
				
			}
		}
		$sql = rtrim($sql , ',');
		return $sql;
	}

	// 处理WHERE条件
	public function handleWhere( $data )
	{
		if(!empty($data) && is_string($data)) return " WHERE ".$data;
		$whereString = '';
		if( !empty( $data ) )
		{
			foreach ($data as $key => $value) {
				if(is_numeric($key))
				{
					$whereString .= "(".$value.") AND";
				}else{
					$whereString .= " `".$key."`='".$value."' AND";
				}
			}
		}else{
			$whereString = ' 1=1 ';
		}
		$whereString = rtrim($whereString , 'AND');
		return ' WHERE '.$whereString;
	}

	// 实现插入操作
	public function insert( $table, $data = array() , $hash = '' ,$getLastId = 1 )
	{
		$table	= !empty($hash) ? $this->TableHash( $table, $hash) : $table;
		$sql	= "INSERT INTO `".$table."` SET ".$this->handleData( $data )." ";
		if($getLastId)
		{
			$c	= $this->query( $sql );
			if( $c === false ) return false;
			$id	= $this->dbobj->lastInsertId();
			unset($c);
			return $id;
		}
		else
		{
			return $this->exec( $sql );
		}
	}

	// 实现更新操作
	public function update( $table, $data = array(), $where = array() , $options = '', $hash = '' )
	{
		$table	= !empty($hash) ? $this->TableHash( $table, $hash) : $table;
		$sql 	= "UPDATE `".$table."` SET ".$this->handleData( $data ).$this->handleWhere($where)." ".$options." ";
		return  $this->exec( $sql );
	}

	// 实现删除操作
	public function delete( $table = '', $where = array(), $options= '', $hash = '' )
	{
		$table	= !empty($hash) ? $this->TableHash( $table, $hash) : $table;
		$sql	= "DELETE FROM  `".$table."` ".$this->handleWhere($where)." ".$options." ";
		return $this->exec($sql);
	}

	// 实现删减操作
	public function truncate( $table )
	{
		$table 	=  $table ?  $table : $this->table;
		$sql 	= "truncate table ".$table;
		return 	$this->query( $sql );
	}

	// 获取数量
	public function count( $table = '',  $where = array(), $options = '', $hash = '' )
	{
		$table	= !empty($hash) ? $this->TableHash( $table, $hash) : $table;
		$sql 	= "SELECT COUNT(1) as c FROM ".$table."  ".$this->handleWhere($where). " ". $options . " LIMIT 1";
		$c		= $this->query($sql);
		if(!$c) return false;
		$data	=  $c->fetch(PDO::FETCH_ASSOC);
		unset($c);
		return (int)$data['c'];
	}

	// 获取单条信息
	public function findOne( $table, $column = "*", $where =  array(), $hash = '', $options = '' )
	{
		$table	= !empty($hash) ? $this->TableHash( $table, $hash) : $table;
		$select	= empty($column) ? " * " :  $column ;
		$sql	= "SELECT ".$column." FROM `".$table."` ".$this->handleWhere($where)." ".$options." LIMIT 1";
		$c		= $this->query( $sql );
		if( !$c )return false;
		$data	= $c->fetch(PDO::FETCH_ASSOC);
		unset($c);
		return $data;
	}

	// 获取列表
	public function findAll( $table, $column = "*", $where = array(), $hash = '',  $start = 0, $limit = 0, $options = '')
	{
		$table		= !empty($hash) ? $this->TableHash( $table, $hash) : $table;
		$column		= empty($column) ? " * " :  $column ;
		$limitString= '';
		if( $start !=0 || $limit !=0 )
		{
			$limitString	= " LIMIT {$start},{$limit}";
		}
		$sql	= "SELECT ".$column." FROM `".$table."` ".$this->handleWhere($where)." ".$options." ".$limitString ;
		$c		= $this->query( $sql );
		if( !$c ) return false;
		$data 	= $c->fetchAll(PDO::FETCH_ASSOC);
		unset($c);
		return $data;
	}

	//获取UUID
	public function findUUid($table = '')
	{
		$tables	= $table ?  $table : $this->table;
		$tables = $tables ? $tables : 'active_user';
		$sql 	= "SELECT uuid() AS 'uuid' FROM `".$tables."`";
		$c		= $this->query( $sql );
		if( !$c )return false;
		$data	= $c->fetch(PDO::FETCH_ASSOC);
		$msg	= !empty($data) ? str_replace('-', '', $data['uuid']): '';
		return $msg;
	}
	// 导出表结构

	public function dump()
	{
		$tables = array();
		$status =array();
		$sql = "SHOW TABLE STATUS";
		$result = $this->dbobj->query($sql)->fetchAll(PDO::FETCH_ASSOC);
		if($result)
		{
			foreach($result as $k=>$v)
			{
				$status[$v['Name']] =  $v;
			}
		}
		if($result)
		{
			foreach($result as $k=>$v)
			{
				$tables[] = $v['Name']; 
			}
		}
		if( !$tables )
		{
			exit('没有任何表');
		}
		// 导出。。
		$thead  = '<tr><th colspan="8" style="background:#33CCFF">{#1#} {#4#} &nbsp;&nbsp;共({#2#})字段 &nbsp;&nbsp;ENGINE({#3#}) {#5#}</th></tr>';
		$th 	= '<tr><th>字段名</th><th>类型</th><th>长度</th><th>无符号</th><th>允许为空</th><th>默认值</th><th>主键</th><th>注释</th></tr>' ;
		
		$string = '<!DOCTYPE HTML><HTML lang="zh_CN"><HEAD><META CHARSET="UTF-8" /><style type="text/css">table{border-collapse:collapse;border-spacing:0;border-left:1px solid #888;border-top:1px solid #888;background:#efefef;}
					th,td{border-right:1px solid #888;border-bottom:1px solid #888;padding:5px 15px;}
					th{font-weight:bold;background:#ccc;}</style></HEAD><BODY>';
		foreach($tables as $k=>$v)
		{
			$string .= '<table width="100%">';
			$tablename =  $v;
			$attr      =  $this->tableAttr($v);
			$count     =  count($attr);
			$string .= str_replace(array('{#1#}','{#2#}','{#3#}','{#4#}', '{#5#}'), array($tablename,$count,$status[$v]['Engine'] , ($status[$v]['Comment'] ? '('.$status[$v]['Comment'].')': '') , $status[$v]['Collation'] ), $thead);
			$string .= $th;
			if($attr)
			{
				foreach($attr as $column)
				{
					//判断
					$string .= '<tr>';
					$string .= '<td>'.$column['Field'].'</td>';
					$typeArray = explode(' ', $column['Type']);

					preg_match('/([a-z]+)((\()([^\)]+)(\)))?/i', $typeArray[0] , $callback);
					$type =  $callback[1];
					$string .= '<td>'.$type.'</td>';
					if(isset($callback[2]))
					{
						$string .= '<td>'.$callback[4].'</td>';	
					}else{
						$string .= '<td></td>';	
					}
					if(isset($typeArray[1]) && !empty($typeArray[1]))
					{
						$string .= '<td>是</td>';	
					}else{
						$string .= '<td></td>';	
					}
					$string .= '<td>'.($column['Null'] == 'Yes' ? '是' : '否').'</td>';
					$string .= '<td>'.$column['Default'].'</td>';
					$string .= '<td>'.($column['Key'] == 'PRI' ? '是' : '').'</td>';
					$string .= '<td>'.$column['Comment'].'</td>';
					$string .= '</tr>';
				}
				
			}
			$string .= '</table><p></p>';
		}
		$string .= '</BODY></HTML>';
		echo $string;
	}

	public function tableAttr( $table )
	{
		$sql 	= "SHOW FULL COLUMNS FROM `".$table."`";
		$result = $this->dbobj->query( $sql )->fetchAll( PDO::FETCH_ASSOC );
		return $result;
	}
}